#include "class_strategy_ba.h"
#include "class_center.h"
#include "class_strategy_position.h"

extern class_center a;
extern lambda_pool pool;


class_strategy_ba::class_strategy_ba(int idd, std::string dm, int n1, double k, double p, int sl)
{
memset(&ints,0,sizeof(ints));
memset(&dous,0,sizeof(dous));

memset(&data,0,sizeof(data));

name = dm;

std::string str = a.path_str + "/strategy";
//if(nullptr == opendir(str.c_str()))
//{
//auto return_value=mkdir(str.c_str(),777);
//if(return_value != 0)
//{
//	std::cout<<"建立目录:"<<str<<"失败！返回值:"<<return_value<<std::endl;
//}
//}
create_path(str);

str = a.path_str + "/strategy/ba";
//if(nullptr == opendir(str.c_str()))
//{
//auto return_value=mkdir(str.c_str(),777);
//if(return_value != 0)
//{
//	std::cout<<"建立目录:"<<str<<"失败！返回值:"<<return_value<<std::endl;
//}
//}
create_path(str);

str = a.path_str + "/strategy/ba/"+dm;
//if(nullptr == opendir(str.c_str()))
//{
//auto return_value=mkdir(str.c_str(),777);
//if(return_value != 0)
//{
//	std::cout<<"建立目录:"<<str<<"失败！返回值:"<<return_value<<std::endl;
//}
//}
create_path(str);

str = a.path_str + "/log/strategy";
//if(nullptr == opendir(str.c_str()))
//{
//auto return_value=mkdir(str.c_str(),777);
//if(return_value != 0)
//{
//	std::cout<<"建立目录:"<<str<<"失败！返回值:"<<return_value<<std::endl;
//}
//}
create_path(str);

str = a.path_str + "/log/strategy/ba";
//if(nullptr == opendir(str.c_str()))
//{
//auto return_value=mkdir(str.c_str(),777);
//if(return_value != 0)
//{
//	std::cout<<"建立目录:"<<str<<"失败！返回值:"<<return_value<<std::endl;
//}
//}
create_path(str);

ints[1] = n1;
ints[2] = sl;
dous[1]=k;
dous[2]=p;

cc = new class_strategy_position(a.path_str + "/strategy/ba/" + dm);

ticks.read(a.path_str+"/ticks/" + name + ".dat", n1+2);
if(a.ticks_map.find(dm) != a.ticks_map.end() )
{
for(auto &v: a.ticks_map[dm].datas)
{
ticks.datas.push_back(v);
}
}

while(ticks.datas.size() > ints[1]*2)
{
ticks.datas.pop_front();
}

		id=idd;
a.tick_event_map[name].insert([this](){ pool.insert([this](){ if(a.flag[50]==1){run_one();} }); },id);
a.log.insert("strategy/ba/"+name,"实例化成功,当前仓位" + std::to_string(cc->position));
}

class_strategy_ba::~class_strategy_ba()
{
a.tick_event_map[name].pop(id);
	a.log.insert("strategy/ba/"+name,"析构完成,当前仓位"+std::to_string(cc->position));
delete cc;
}


// 主执行函数
void class_strategy_ba::run_one()
{


//清理报单返回值
a.return_erase(*cc);
//同步持仓
a.position_sync(*cc);
//获取到TICK
data=a.tick_map[name];

//获取行情到ticks队列
ticks.insert(data);
if (ticks.datas.size() < (ints[1] + 2) || a.flag[35] == 0)
{
	std::cout<<"比例"<<name<<"tick数量"<<ticks.datas.size()<<std::endl;
return;
}

//计算
dous[5]=accumulate(ticks.datas.rbegin(), ticks.datas.rbegin() + ints[1], 0.0, [&](double x, class_tick::struct_tick &y){return x + (y.LastPrice == data.LastPrice ? y.BidVolume1 : 0);}); 
dous[6]=accumulate(ticks.datas.rbegin(), ticks.datas.rbegin() + ints[1], 0.0, [&](double x, class_tick::struct_tick &y){return x + (y.LastPrice == data.LastPrice ? y.AskVolume1 : 0);}); 
dous[7] = (dous[5]  > 0 ? dous[5] / (dous[5] + dous[6]) : 0);

ticks.datas.pop_front();//删除最早的

//如果处于买入区且仓位不够则
if (dous[7] > dous[1] && cc->position < ints[2] && cc->return_vector.size() == 0)
{
a.bd_auto(data.InstrumentID, '0', data.UpperLimitPrice, 1, *cc);
a.log.insert("strategy/ba/" + name +"交易", name + "多开动作" + std::to_string(data.AskPrice1));
return;
}

if (dous[7] < (1 - dous[1]) && cc->position > 0 - ints[2] && cc->return_vector.size() == 0)
{
a.bd_auto(data.InstrumentID, '1', data.LowerLimitPrice, 1, *cc);
a.log.insert("strategy/ba/" + name + "交易", name + "空开动作" + std::to_string(data.BidPrice1));
return;
}

if (dous[7] < dous[2] && cc->position > 0 && cc->return_vector.size() == 0)
{
a.bd_auto(data.InstrumentID, '1', data.LowerLimitPrice, 1,*cc);
a.log.insert("strategy/ba/" + name + "交易", name + "多头平仓" + std::to_string(data.BidPrice1));
return;
}

if (dous[7] > (1-dous[2]) && cc->position < 0 && cc->return_vector.size() == 0)
{
a.bd_auto(data.InstrumentID, '0', data.UpperLimitPrice, 1, *cc);
a.log.insert("strategy/ba/" + name + "交易", name + "空头平仓" + std::to_string(data.BidPrice1));
}

return;
}
